#pragma once

#include <iostream>
#include <time.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

using namespace std;

#define SIZE 4096

// enum class LogLevel
// {
//     INFO,
//     DEBUG,
//     WARNING,
//     ERROR,
//     FATAL
// };

enum LogLevel
{
    INFO,
    DEBUG,
    WARNING,
    ERROR,
    FATAL
};

class Log
{
public:
	string LevelToString(int level) //需要传入枚举类型，我们使用的是枚举类进行进行判断
	{
	    switch(level)
	    {
	        // case LogLevel::INFO :
	        // return "INFO";
	        // case LogLevel::DEBUG :
	        // return "DEBUG";
	        // case LogLevel::WARNING :
	        // return "WARNING";
	        // case LogLevel::ERROR :
	        // return "ERROR";
	        // case LogLevel::FATAL :
	        // return "FATAL";

			case INFO :
	        return "INFO";
	        case DEBUG :
	        return "DEBUG";
	        case WARNING :
	        return "WARNING";
	        case ERROR :
	        return "ERROR";
	        case FATAL :
	        return "FATAL";
			default : return "none";
	    }
		
	    return "none";
	}
	
	void operator()(int Log_Level, const char *format, ...)
	{
	    //左半部分 日志等级 + 日志时间
	    time_t t = time(nullptr);
	    struct tm* pt = localtime(&t);
	    char leftbuffer[SIZE];
	    snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d]: ",
	    LevelToString(Log_Level).c_str(),
	    pt->tm_year + 1900, pt->tm_mon + 1, pt->tm_mday,
	    pt->tm_hour, pt->tm_min, pt->tm_sec);

	    //右半部分 自定义部分
	    va_list s;
	    va_start(s, format);
	    char rightbuffer[SIZE];
		//第三个参数不能使用%s或者其他格式控制，需要放入format进行格式错误，不然容易造成段错误
	    vsnprintf(rightbuffer, sizeof(rightbuffer), format, s); 
	    va_end(s);
	
 	//进行打印
		char buffer[SIZE * 2];
		snprintf(buffer, sizeof(buffer), "%s %s", leftbuffer, rightbuffer);
		printf("%s\n", buffer);
	    // fprintf(stdout, "%s%s", leftbuffer, rightbuffer);

	    return;
	}
};

Log lg;

// int main()
// {
// 	Log lg;
//     lg(INFO, "%s", "HelloWorld\n");


//    return 0;
// }



// int sum(int n, ...)
// {
//     va_list s; //定义一个s变量
//     va_start(s, n); //初始化

//     int total = 0;
//     for(int i = 0; i < n; ++i)
//     {
//         total += va_arg(s, int);      
//     }
    
//     va_end(s);

//     return total;    
// }

// int main()
// {
//     printf("total: %d\n", sum(3, 1, 2, 3));

//     return 0;
// }


// #include <iostream>
// #include <time.h>
// #include <stdarg.h>
// #include <sys/types.h>
// #include <sys/stat.h>
// #include <fcntl.h>
// #include <unistd.h>
// #include <stdlib.h>

// #define SIZE 1024

// #define Info 0
// #define Debug 1
// #define Warning 2
// #define Error 3
// #define Fatal 4

// #define Screen 1
// #define Onefile 2
// #define Classfile 3

// #define LogFile "log.txt"

// class Log
// {
// public:
//     Log()
//     {
//         printMethod = Screen;
//         path = "./log/";
//     }
//     void Enable(int method)
//     {
//         printMethod = method;
//     }
//     std::string levelToString(int level)
//     {
//         switch (level)
//         {
//         case Info:
//             return "Info";
//         case Debug:
//             return "Debug";
//         case Warning:
//             return "Warning";
//         case Error:
//             return "Error";
//         case Fatal:
//             return "Fatal";
//         default:
//             return "None";
//         }
//     }

//     void logmessage(int level, const char *format, ...)
//     {
//         time_t t = time(nullptr);
//         struct tm *ctime = localtime(&t);
//         char leftbuffer[SIZE];
//         snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d]", levelToString(level).c_str(),
//                  ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday,
//                  ctime->tm_hour, ctime->tm_min, ctime->tm_sec);

//         va_list s;
//         va_start(s, format);
//         char rightbuffer[SIZE];
//         vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);
//         va_end(s);

//         // 格式：默认部分+自定义部分
//         char logtxt[SIZE * 2];
//         snprintf(logtxt, sizeof(logtxt), "%s %s\n", leftbuffer, rightbuffer);

//         // printf("%s", logtxt); // 暂时打印
//         printLog(level, logtxt);
//     }
//     void printLog(int level, const std::string &logtxt)
//     {
//         switch (printMethod)
//         {
//         case Screen:
//             std::cout << logtxt << std::endl;
//             break;
//         case Onefile:
//             printOneFile(LogFile, logtxt);
//             break;
//         case Classfile:
//             printClassFile(level, logtxt);
//             break;
//         default:
//             break;
//         }
//     }
//     void printOneFile(const std::string &logname, const std::string &logtxt)
//     {
//         std::string _logname = path + logname;
//         int fd = open(_logname.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0666); // "log.txt"
//         if (fd < 0)
//             return;
//         write(fd, logtxt.c_str(), logtxt.size());
//         close(fd);
//     }
//     void printClassFile(int level, const std::string &logtxt)
//     {
//         std::string filename = LogFile;
//         filename += ".";
//         filename += levelToString(level); // "log.txt.Debug/Warning/Fatal"
//         printOneFile(filename, logtxt);
//     }

//     ~Log()
//     {
//     }
//     void operator()(int level, const char *format, ...)
//     {
//         time_t t = time(nullptr);
//         struct tm *ctime = localtime(&t);
//         char leftbuffer[SIZE];
//         snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d]", levelToString(level).c_str(),
//                  ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday,
//                  ctime->tm_hour, ctime->tm_min, ctime->tm_sec);

//         va_list s;
//         va_start(s, format);
//         char rightbuffer[SIZE];
//         vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);
//         va_end(s);

//         // 格式：默认部分+自定义部分
//         char logtxt[SIZE * 2];
//         snprintf(logtxt, sizeof(logtxt), "%s %s", leftbuffer, rightbuffer);

//         printf("%s\n", logtxt); // 暂时打印
//         // printLog(level, logtxt);
//     }

// private:
//     int printMethod;
//     std::string path;
// };